package com.faxsun.core.web.security.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.broadleafcommerce.common.util.BLCSystemProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.faxsun.captcha.constants.CaptchaType;
import com.faxsun.core.web.security.FraudConstants;
import com.faxsun.core.web.security.FraudConstants.FraudEnableLevel;
import com.faxsun.fm.model.LoginRequest;
import com.faxsun.fm.model.Response;
import com.faxsun.fm.model.SignUpRequest;
import com.faxsun.fm.model.Response.Action;
import com.faxsun.service.FraudMetrixService;

@Service("fsFraudService")
public class FraudServiceImpl implements FraudService {

	@Autowired
	protected FraudMetrixService fraudMetrixService;

	/**
	 * 查询当前request对应的风控策略，并根据返回结果设置session验证所需的信息
	 */
	@Override
	public Response queryFraudForLogin(HttpServletRequest request) {

		return processLoginRequest(request, null);

	}

	/**
	 * 将登录结果通知到风控策略中心
	 */
	@Override
	public void noitfyFraudLoginResult(HttpServletRequest request,
			Boolean isSucc) {

		processLoginRequest(request, isSucc);

	}

	/**
	 * 处理登录风控事件请求
	 * @param request
	 * @param isSucc
	 * @return
	 */
	private Response processLoginRequest(HttpServletRequest request,
			Boolean isSucc) {
		FraudEnableLevel level = this.getFraudEnableLevel();
		if (!level.equals(FraudEnableLevel.DISABLE)) {
			// 查询请求
			LoginRequest loginRequest = (LoginRequest) buildRequest(request,
					LoginRequest.class, isSucc);
			// 查询结果
			Response resp = fraudMetrixService.loginService(loginRequest);
			return processResponse(request, resp);
		}

		return null;
	}

	/**
	 * 查询当前注册事件的风控策略
	 */
	@Override
	public Response queryFrauadForRegister(HttpServletRequest request) {

		return processRegisterRequest(request, null);
	}

	/**
	 * 将当前注册结果通知风控策略中心
	 */
	@Override
	public void notifyFrauadRegisterResult(HttpServletRequest request,
			Boolean isSucc) {

		processRegisterRequest(request, isSucc);
	}

	/**
	 * 注册事件风控请求处理
	 * 
	 * @param request
	 * @param isSucc
	 * @return
	 */
	private Response processRegisterRequest(HttpServletRequest request,
			Boolean isSucc) {

		FraudEnableLevel level = this.getFraudEnableLevel();
		if (!FraudEnableLevel.DISABLE.equals(level)) {
			// 查询请求
			SignUpRequest loginRequest = (SignUpRequest) buildRequest(request,
					SignUpRequest.class, isSucc);
			// 查询结果
			Response resp = fraudMetrixService.signUpService(loginRequest);
			return processResponse(request, resp);
		}

		return null;
	}

	/**
	 * 根据Response，session中设置需要的风控应对方式
	 * 
	 * @param request
	 * @param resp
	 * @return
	 */
	private Response processResponse(HttpServletRequest request, Response resp) {
		Boolean isCaptchaRequired = Boolean.FALSE;
		Action action = resp.getAction();
		HttpSession session = request.getSession();
		if (action.equals(Action.SMS)
				|| action.equals(Action.VERIFICATION_CODE)) {
			// 风控行为
			isCaptchaRequired = Boolean.TRUE;
			switch (action) {
			case SMS:
				session.setAttribute(FraudConstants.CAPTCH_TYPE,
						CaptchaType.SMS_DIGITAL);
				break;
			case VERIFICATION_CODE:
				session.setAttribute(FraudConstants.CAPTCH_TYPE,
						CaptchaType.IMG_DIGITAL_CHAR);
				break;
			default:
				break;

			}
		}
		FraudEnableLevel level = this.getFraudEnableLevel();
		switch (level) {
		case DISABLE:
		case ENABLE:
			return null;
		default:
			return null;
		case VALIDATE:
			session.setAttribute("isCaptchaRequired", isCaptchaRequired);
			return resp;

		}
	}

	/**
	 * 获取后台风控生效级别。Cache过期时间需设置system.property.cache.timeout，
	 * 
	 * @return
	 */
	private FraudEnableLevel getFraudEnableLevel() {
		int level = BLCSystemProperty
				.resolveIntSystemProperty(FraudConstants.FRAUD_LEVEL_PROPERTY);
		FraudEnableLevel levelVar = FraudConstants.FraudEnableLevel
				.parseInt(level);
		return levelVar;
	}

	/**
	 * 根据request、需要的Request类型，及事件结果，构造风控策略请求
	 * 
	 * @param request
	 * @param clazz
	 * @param isSucc
	 * @return
	 */
	private Object buildRequest(HttpServletRequest request,
			@SuppressWarnings("rawtypes") Class clazz, Boolean isSucc) {
		String tokenId = "";
		tokenId = request.getParameter("csrfToken");
		

		// 风控事件结果，成功为1，失败为0
		String state = isSucc == null ? "" : (isSucc ? "1" : "0");

		Object object = null;

		if (SignUpRequest.class.equals(clazz)) {
			String accountLogin = request.getParameter("customer.emailAddress");
			object = new SignUpRequest(tokenId, accountLogin, state,
					accountLogin, "", "", "", "",
					((ServletRequestAttributes) RequestContextHolder
							.currentRequestAttributes()).getRequest());
		} else if (LoginRequest.class.equals(clazz)) {
			String accountLogin = request.getParameter("j_username");
			object = new LoginRequest(tokenId, accountLogin, state, "",
					((ServletRequestAttributes) RequestContextHolder
							.currentRequestAttributes()).getRequest());
		}
		return object;

	}
}
